

#ifndef __UTILS_MESHCREATOR_H__
#define __UTILS_MESHCREATOR_H__

#include <export.h>
#include <gfx/idevice.h>
#include <gfx/ibillboardmesh.h>
#include <gfx/iinstancedmesh.h>
#include <gfx/imorphmesh.h>
#include <gfx/ipatchmesh.h>
#include <gfx/istaticmesh.h>
#include <math/vector.h>

/**
 * \addtogroup utils
 * @{
 */

/**
 * @brief Utility class for simple mesh creation.
 */

class CE_API ceMeshCreator
{
private:
  iDevice*	_device;

  struct Vertex
  {
    ceVector3f  XYZ;
    ceVector3f  Normal;
    ceVector2f  UV;
  };

  std::vector<Vertex>   _vertices;
  std::vector<unsigned> _indices;

  ceVector3f CalcTerrainNormal (const float* heights, unsigned i, unsigned j, unsigned numI, unsigned numJ, float distI, float distJ);
  void SmoothTerrainNormals (float* vertexData, unsigned offset, unsigned stride, unsigned numI, unsigned numJ);

public:
  ceMeshCreator ();

  bool Initialize (iDevice* device);

  ceRef<iPatchMesh> CreateTerrain (const ceVector3f&	min,
														 const ceVector3f& max, 
														 unsigned					numVerticesP, 
														 unsigned					numVerticesQ, 
														 const float*			heights, 
														 unsigned					numPatchesP, 
														 unsigned					numPatchesQ, 
														 float						patchDistance, 
														 bool							invertP = false,
														 bool							invertQ = false,
														 bool							createTangents = false);

  void Clear ();
  void AddVertex (const ceVector3f& xyz, const ceVector3f& normal = ceVector3f (0, 0, 1), const ceVector2f& uv = ceVector2f (0, 0));
  void AddLine (unsigned i0, unsigned i1);
  void AddTrigon (unsigned i0, unsigned i1, unsigned i2);
  void AddQuad (unsigned i0, unsigned i1, unsigned i2, unsigned i3);
  ceRef<iStaticMesh> CreateStaticMesh (cePrimitiveType type = PT_Triangles);
};

/** @} */

#endif /* ! __UTILS_TERRAINCREATOR_H__ */
